package RRDSet;

# TODO:
# - is database necessary

use strict;
use warnings;
use Carp;
use RRD;
use RRD::Fields ':all';
use Time::HiRes 'time';

our %masters;
our %connections;

sub new
{
  my ($class, $config) = @_;

  my $interval = $config->{interval} || 60;
  my $directory = $config->{directory} || '.';

  my @rrds;
  my ($host_id, $host_config);
  while (($host_id, $host_config) = each %{$config->{hosts}})
  {
    my $db = get_db (
      $host_id,
      $host_config->{host} || 'localhost',
      $host_config->{port} || 3600,
      $host_config->{database} || 'mysql',
      $host_config->{user} || $config->{user} || 'stats',
      $host_config->{pass} || $config->{pass},
    );
    push (@rrds, RRD->new (
        filename => $directory.'/'.$host_id.'.rrd',
        db => $db,
        # for now it's just the host_id, we'll go back and replace in a sec
        master_db => $host_config->{master},
        fields => $host_config->{fields} || $config->{fields} || 
          default_fields,
      ));
    $rrds[-1]->create ($interval);
  }

  # we're going back through for these so that we don't have to 
  foreach (@rrds)
  {
    unless ($_->{master_db})
    {
      delete ($_->{master_db});
      next;
    }
    my $master_id = $_->{master_db};
    # this will only fetch existing, won't create new ones
    $_->{master_db} = get_db ($master_id);
    croak "undefined master ($master_id)" unless ($_->{master_db});
  }

  bless ({ 
      rrds => \@rrds,
      interval => $interval,
    }, $class);
}

sub run
{
  my ($self, $until) = @_;

  my ($start, $dur);
  while (not $until or $until < time)
  {
    $start = time;
    $_->run foreach (@{$self->{rrds}});
    $dur = time - $start;
    if ($dur > 50)
    {
      die "took $dur seconds to run, too many hosts. time to multi-thread this stuff, let author know\n";
    }
    # subtract off the time it takes us to run (rounded to nearest second)
    # from the amount of time we sleep to attempt to keep things closer to
    # 1 minute interval
    sleep (int ($self->{interval} - $dur + 0.5));
  }
}

sub get_db
{
  my ($host_id, $host, $port, $database, $user, $pass) = @_;

  my $connection = $connections{$host_id};

  unless ($connection)
  {
    return undef unless ($host);
    $connection = DB->new (
      host => $host,
      port => $port,
      database => $database,
      user => $user,
      pass => $pass,
    );
    $connections{$host_id} = $connection;
  }

  $connection;
}

1;
